EMatrix GetRangeMatrix( const EMatrix &iVP, const EMatrix &newVP, const EPlane &water, float wave_h )
{
	//	make bound planes :
	EPlane upper = water.normalize();
	EPlane lower = water.normalize();

	upper.d -= wave_h;
	lower.d += wave_h;
	
	std::vector<EPoint>	buffer;

	//	transform frustum conrners to world space :
	float	u	=	1;
	EVector	v0	=	EVector( u, u, u).Transform(iVP);
	EVector	v1	=	EVector(-u, u, u).Transform(iVP);
	EVector	v2	=	EVector(-u,-u, u).Transform(iVP);
	EVector	v3	=	EVector( u,-u, u).Transform(iVP);
	EVector	v4	=	EVector( u, u,-u).Transform(iVP);
	EVector	v5	=	EVector(-u, u,-u).Transform(iVP);
	EVector	v6	=	EVector(-u,-u,-u).Transform(iVP);
	EVector	v7	=	EVector( u,-u,-u).Transform(iVP);
	
	//rs()->GetDVScene()->DrawPoint( v0, 0.1f, EVec4(1,1,0,0.5) );
	//rs()->GetDVScene()->DrawPoint( v1, 0.1f, EVec4(1,1,0,0.5) );
	//rs()->GetDVScene()->DrawPoint( v2, 0.1f, EVec4(1,1,0,0.5) );
	//rs()->GetDVScene()->DrawPoint( v3, 0.1f, EVec4(1,1,0,0.5) );
	//rs()->GetDVScene()->DrawPoint( v4, 0.1f, EVec4(1,0,1,1.0) );
	//rs()->GetDVScene()->DrawPoint( v5, 0.1f, EVec4(1,0,1,1.0) );
	//rs()->GetDVScene()->DrawPoint( v6, 0.1f, EVec4(1,0,1,1.0) );
	//rs()->GetDVScene()->DrawPoint( v7, 0.1f, EVec4(1,0,1,1.0) );

	struct segment_s {
		void fromVec4( const EVector &a, const EVector &b ) {
			this->a	=	a;
			this->b	=	b;
		}
		EVector a, b;
	};
	
	segment_s s[12];
	
	s[ 0].fromVec4(	v0,	v1 );	s[ 1].fromVec4(	v1,	v2 );
	s[ 2].fromVec4(	v2,	v3 );	s[ 3].fromVec4(	v3,	v0 );
	
	s[ 4].fromVec4(	v4,	v5 );	s[ 5].fromVec4(	v5,	v6 );
	s[ 6].fromVec4(	v6,	v7 );	s[ 7].fromVec4(	v7,	v4 );
	
	s[ 8].fromVec4(	v0,	v4 );	s[ 9].fromVec4(	v1,	v5 );
	s[10].fromVec4(	v2,	v6 );	s[11].fromVec4(	v3,	v7 );
	
	EPoint	corners[8] = { 
		EPoint(v0), 	EPoint(v1), 	EPoint(v2), 
		EPoint(v3), 	EPoint(v4), 	EPoint(v5), 
		EPoint(v6), 	EPoint(v7)
	};
	
	
	//	add intersections :
	for (uint i=0; i<12; i++) {
		EVector a = s[i].a;
		EVector b = s[i].b;
		
		float frac;
		
		if ( upper.traceSegment( EPoint(a), EPoint(b), frac ) ) {
			EVector p	=	a + (b-a) * frac;
			buffer.push_back( EPoint( p ) );
		}
		
		if ( lower.traceSegment( EPoint(a), EPoint(b), frac ) ) {
			EVector p	=	a + (b-a) * frac;
			buffer.push_back( EPoint( p ) );
		}
	}
	
	//	add corners :
	for (uint i=0; i<8; i++) {
		if ( upper.classifyPoint( corners[i], 0 )<=0 && lower.classifyPoint( corners[i], 0 )>=0 ) {
			buffer.push_back( corners[i] );
		}
	}
	
	EBBox bbox;
	bbox.MakeSingular();
	
	if (buffer.empty()) {
		return EMatrix();
	}
	
	for (uint i=0; i<buffer.size(); i++) {
		buffer[i].z = 0;

		//rs()->GetDVScene()->DrawPoint( buffer[i], 0.1, EVec4(0,0,1,1.0) );
		
		EPoint tp = buffer[i].Transform( newVP );
		bbox.Expand( tp );
	}
	
	float xmin = bbox.Min().x;
	float xmax = bbox.Max().x;
	float ymin = bbox.Min().y;
	float ymax = bbox.Max().y;
	
	//LOGF("X:[%f %f] Y:[%f %f]", xmin, xmax, ymin, ymax);
	
	EMatrix	m2 (
			xmax - xmin,		0,				0,		0,	
				0,			ymax - ymin,		0,		0,
				0,				0,				1,		0,
			(xmin+xmax)/2,	(ymin+ymax)/2,		0,		1	
		);	//*/
		
	return m2;
}


//
//	EWaving::Update
//
void EWaving::Update( float dtime, const EPoint &view_pos, const EQuaternion &orient )
{

	r_sky->SetPose( view_pos, EQuaternion() );
	return;
#if 0	
	//PROFILE_FUNCTION("");
	
	time	+=	dtime;

	//r_sky->SetFlag( RSE_HIDDEN );
	//r_ent->SetFlag( RSE_HIDDEN );
	
	uint sw, sh;
	rs()->GetScreenSize(sw, sh);
	float aspect = (float)sw / (float)sh;
	
	EPoint			view_position;
	EQuaternion		view_orient;
	EFrustum		view_frustum;

	rs()->GetFRScene()->GetViewProj( view_frustum, view_position, view_orient );

	EFrustum	Fr		=	view_frustum;
	float		w		=	Fr.getWidth();
	float		h		=	Fr.getHeight();
	float		zn		=	Fr.getZNear();
	float		zf		=	Fr.getZFar();

	EMatrix	T		=	EMatrix::Translate( -EVector(view_position) );
	EMatrix	R		=	view_orient.Inverse().ToMatrix();
	EMatrix	V		=	T * R;
	EMatrix	P		=	EMatrix::PerspectiveRH( zn/zf*w, zn/zf*h, zn, zf );
	EPlane		water(0,0,1,0);
	
	EMatrix	VP		=	V * P;
	EMatrix	iVP		=	( V * P ).Inverse();
	EMatrix	newiVP;
	EMatrix	newVP;
	EMatrix	newV;
	EMatrix	newP;
	
	
	//
	//	Make projector matrix :
	//
	do {
	
		EPoint	center	=	view_position;
		float	cam_h	=	center.z;
		center.z		=	0;

		//	find view ray-water intersection point :
		EPoint r0	=	EPoint(0,0, 0).Transform( iVP );
		EPoint r1	=	EPoint(0,0, 1).Transform( iVP );

		EPoint p;		
		EPoint o		= r0;
		//EVec4 r	= Vec4Normalize( r1 - r0 );
		EVector r		= r1 - r0;
		
		float t		= PlaneTraceRayAgainstPlane(p, o, r, water );
		
		const float RANGE = 0.5f;
		
		if ( t < 0 ) {
			t = RANGE;
		}
		if ( t > RANGE ) {
			t = RANGE;
		}
		
		p = o + r * t;
		p.z = 0;
		
		//rs()->GetDVScene()->DrawPoint( p, 2.0f, EVec4(1,0,0,1.0));
		
		//	elevate camera :
		float c_p_dist	=	( EVector(center.x, center.y, 0) - EVector(p.x, p.y, 0) ).Length();
		float elev		=	h * c_p_dist / 2 / zf;
		
		elev			=	clamp<float>( elev, cam_h, 100000 );
		
		newV			=	EMatrix::LookAtRH( EPoint(center.x, center.y, elev), p, EVector(0,0,1) );
		newP			=	P;
		newVP			=	newV * newP;
		newiVP			=	( newV * newP ).Inverse();
		
	} while (0);
	
	EMatrix	range	=	GetRangeMatrix( iVP, newVP, water, 10 );

	//
	//	Make grid :
	//
	IPxTriMesh	mesh	=	sea_mesh->Clone();
	uint n = mesh->GetVertexNum();
	
	EMatrix	Tproj	=	range * newiVP;

#if 1
	for (uint i=0; i<n; i++) {
		EVertex	v;
		
		v			=	mesh->GetVertex( i );
		float x		=	v.position.x*0.5;
		float y		=	v.position.y*0.5;
		
		EPoint r0	=	EPoint(x,y,-1).Transform( Tproj );
		EPoint r1	=	EPoint(x,y, 1).Transform( Tproj );
		

		EPoint p;		
		EPoint o = r0;
		EVector r = r1 - r0;
		float t = PlaneTraceRayAgainstPlane(p, o, r, water );
		if (t>1) { t = 1; }
		if (t<0) { t = 1; }
		
		p	=	o + r*t;
		
		
		//
		//	write vertex :
		//		
		v.position.x	=	p.x;
		v.position.y	=	p.y;
		v.position.z	=	GetWaveFast( v.position.x, v.position.y, time );
		
		float	dist	=	( EPoint(p.x, p.y, 0) - view_pos ).Length();
				dist	=	clamp<float>( dist, 0, zf);
		
		float	wave_factor	=	pow(1 - abs(dist/zf), 0.25f);

		v.position.z *=	wave_factor;
		
		//rs()->GetDVScene()->DrawPoint( EVec4(v.position.x, v.position.y, v.position.z, 1), 0.1, EVec4(0,0,1,1) );
		
		mesh->SetVertex( i, v );
	}
#endif	
	
	
	//
	//	post process mesh :
	//
	mesh->ComputeNormals();


	for (uint i=0; i<n; i++) {
		EVertex	v	=	mesh->GetVertex( i );
		v.uv0.x		=	v.position.x/4;
		v.uv0.y		=	v.position.y/4;
		
		float	r	=	v.normal.z;
		float	g	=	v.position.z;
		v.color0	=	EColor(r,g,0,1);
		
		mesh->SetVertex( i, v );
	}

	uint format = mesh->GetFormat();
	//mesh->SetFormat( format | GE_MESH_BINORMAL | GE_MESH_TANGENT );
	//r_ent->SetMesh( mesh, true );
	r_ent->SetFlag( RSE_HIDDEN );  
#endif	
}
